﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// 
    /// </summary>
    public class TemplateHost : Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="optionName"></param>
        /// <returns></returns>
        public object GetHostOption(string optionName)
        {
            object obj = null;
            switch (optionName)
            {
                case "CacheAssemblies":
                    obj = true;
                    break;
                default:
                    obj = null;
                    break;
            }
            return obj;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="requestFileName"></param>
        /// <param name="content"></param>
        /// <param name="location"></param>
        /// <returns></returns>
        public bool LoadIncludeText(string requestFileName, out string content, out string location)
        {
            content = string.Empty;
            location = string.Empty;
            if (System.IO.File.Exists(requestFileName))
            {
                content = System.IO.File.ReadAllText(requestFileName);
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="errors"></param>
        public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors)
        {
            this.errors = errors;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public AppDomain ProvideTemplatingAppDomain(string content)
        {
            return AppDomain.CreateDomain("Generation App Domain");
        }

        /// <summary>
        /// 移除类库的引用
        /// </summary>
        /// <param name="assemblyReference"> 类库 </param>
        /// <returns></returns>
        public string ResolveAssemblyReference(string assemblyReference)
        {
            if (System.IO.File.Exists(assemblyReference))
                return assemblyReference;
            string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.TemplateFile), assemblyReference);
            if (System.IO.File.Exists(path))
                return path;
            else
                return string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="processorName"></param>
        /// <returns></returns>
        public Type ResolveDirectiveProcessor(string processorName)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="directiveId"></param>
        /// <param name="processorName"></param>
        /// <param name="parameterName"></param>
        /// <returns></returns>
        public string ResolveParameterValue(string directiveId, string processorName, string parameterName)
        {
            if (string.IsNullOrEmpty(directiveId))
            {
                throw new ArgumentNullException("the directiveId cannot be null");
            }
            if (string.IsNullOrEmpty(processorName))
            {
                throw new ArgumentNullException("the processorName cannot be null");
            }
            if (string.IsNullOrEmpty(parameterName))
            {
                throw new ArgumentNullException("the parameterName cannot be null");
            }
            return string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string ResolvePath(string path)
        {
            if (string.IsNullOrEmpty(path))
                throw new Exception("文件路径不能为空!");
            string newpath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.TemplateFile), path);
            if (System.IO.File.Exists(newpath))
                return newpath;
            else
                return path;
        }

        /// <summary>
        /// 设置文件后缀名
        /// </summary>
        /// <param name="extension"></param>
        public void SetFileExtension(string extension)
        {
            this.fileExtension = extension;
        }

        /// <summary>
        /// 设置输出的编码格式
        /// </summary>
        /// <param name="encoding"></param>
        /// <param name="fromOutputDirective"></param>
        public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective)
        {
            this.fileEncoding = encoding;
        }

        /// <summary>
        /// 获取引用的类库集合。
        /// </summary>
        public IList<string> StandardAssemblyReferences
        {
            get
            {
                return new string[] { 
                    typeof(System.Uri).Assembly.Location,
                    typeof(System.Xml.IHasXmlNode).Assembly.Location,
                    typeof(System.Xml.Linq.Extensions).Assembly.Location,
                    typeof(System.Reflection.Assembly).Assembly.Location,
                    typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly.Location,
                    typeof(System.CodeDom.CodeArgumentReferenceExpression).Assembly.Location,
                    typeof(System.Linq.EnumerableQuery).Assembly.Location
                };
            }
        }

        /// <summary>
        /// 获取引用的命名空间集合。
        /// </summary>
        public IList<string> StandardImports
        {
            get
            {
                return new string[] { 
                    "System",
                    "System.Text",
                    "System.Collections.Generic",
                    "System.ComponentModel",
                };
            }
        }

        #region 属性

        private string templateFile;
        /// <summary>
        /// 模板文件
        /// </summary>
        public string TemplateFile
        {
            get { return this.templateFile; }
            set { this.templateFile = value; }
        }

        private Encoding fileEncoding = Encoding.UTF8;
        /// <summary>
        /// 文件编码格式
        /// </summary>
        public Encoding FileEncoding
        {
            get { return fileEncoding; }
            set { this.fileEncoding = value; }
        }

        private string fileExtension = ".cs";
        /// <summary>
        /// 文件后缀名
        /// </summary>
        public string FileExtension
        {
            get { return fileExtension; }
            set { this.fileExtension = value; }
        }

        private System.CodeDom.Compiler.CompilerErrorCollection errors;
        /// <summary>
        /// 获取错误列表
        /// </summary>
        public System.CodeDom.Compiler.CompilerErrorCollection Errors
        {
            get { return errors; }
        }

        #endregion

    }
}
